#include "TextToPcm.h"
#include <iostream>
#include <thread>
#include <string>

using namespace std;

static string default_history_file_path = "../pcmfiles/outputPcmData.pcm";

TextToPcm::TextToPcm()
{

    static GMainLoop *loop = g_main_loop_new(nullptr, FALSE);
    std::thread eventThread([]()
                            {
        g_main_loop_run(loop);
        g_main_loop_unref(loop); 
        }
        );
    eventThread.detach();

    synthesizer_config = audio_config_create_audio_output_from_pcm_data(); //audio_config_create_audio_output_from_default_speaker()

    session = speech_synthesizer_create_session();

    model_config = speech_model_config_create();

    speech_model_config_set_name(model_config, "讯飞-语音大模型"); // 或"讯飞-语音大模型"百度-语音大模型
    speech_model_config_set_deploy_type(model_config, ModelDeployType::PublicCloud);

    speech_synthesizer_set_model_config(session, model_config);

    speech_synthesizer_result_set_callback(session, model_callback, this);

    speech_synthesizer_init_session(session);

    audio_config_set_input_audio_rate(synthesizer_config, 16000);
    speech_synthesizer_set_audio_config(session, synthesizer_config);


}


TextToPcm::~TextToPcm(){

    

}

void TextToPcm::model_callback(SpeechSynthesisResult *result, void *user_data) {

    // cout << "------------\n";
    // cout << speech_synthesis_result_get_audio_format(result) << endl;
    // cout << "------------\n";
    TextToPcm *self = static_cast<TextToPcm *>(user_data);

    // fprintf(stdout, "开始写入语音文件.\n");

    const char *user_data_str = static_cast<const char*>(user_data);

    uint32_t audio_data_length;
    const uint8_t* audio_data = speech_synthesis_result_get_data(result, &audio_data_length);
    SpeechResultReason result_type = speech_synthesis_result_get_reason(result);

    fprintf(stdout,
            "当前输出标记=%i 本次写入数据长度=%i\n",
            static_cast<int>(result_type),
            static_cast<int>(audio_data_length));
    //         // user_data_str ? user_data_str : "(null)");

    cout << ".";

    if (static_cast<int>(result_type) != 8 ) {
        std::vector<char> data { audio_data, audio_data + audio_data_length };
        write_binary_data_to_file(default_history_file_path, data);
    } else {
        std::vector<char> data { audio_data, audio_data + audio_data_length };
        write_binary_data_to_file(default_history_file_path, data);
        
        
        {
            std::lock_guard<std::mutex> lock(self->sync_mutex);
            self->reply_ready = true;
        }
        self->cv.notify_one();
        
        fprintf(stdout, "\n语音文件写入完成.\n");

    }
    
    
}

void TextToPcm::write_binary_data_to_file(std::string file_name, std::vector<char> &data) {
    // if (data.size() == 0) {
    //     fprintf(stderr, "接收到的数据为空!\n");
    //     return;
    // } else {
    //     std::cout << "开始接收到语音数据.\n";
    // }

    std::ofstream output_file(file_name, std::ios::out | std::ios::binary | std::ios::app);
    if (!output_file.is_open()) {
        fprintf(stderr, "语音输出文件打开失败.\n");
        return;
    }

    output_file.write(reinterpret_cast<const char*>(data.data()), data.size());
    output_file.close();
}


string TextToPcm::run_model(string input_text){

    {
        std::lock_guard<std::mutex> lock(sync_mutex);
        reply_ready = false;
    }

    speech_synthesizer_synthesize_text_async(session, input_text.c_str(), input_text.size());
    
    // 等待回调通知
    std::unique_lock<std::mutex> lock(sync_mutex);
    cv.wait(lock, [this]()
            { return reply_ready; });

    return "---text transform to pcm is ok---";

}